const express = require("express");
const http = require("http");//起服务
const path = require("path");//Node 自带模块 - 拆分目录
const logger = require('morgan');//处理日志
const cors = require("cors");//后端解决跨域问题
const connect = require("./utils/connect.js");//执行app.js时连接数据库
var session = require('express-session');//处理session
var cookieParser = require('cookie-parser');
var createError = require('http-errors');
// 设置路由
//服务器路由 - routes中的路由(单个js;下面中间件设置的别名是路由的上一级目录)  注意: 不用写才分目录; 在app.js里面是app.get/在router里面是router.get
// 地址栏: app.js中的别名 + 路由的path
var vueRouter = require('./routes/vue');


// 进程.开发环境.端口 || 3000
// www文件比起服务多normalizePort(处理端口),onError(错误回调),onListening(listening回调).
const port = 3000;
const hostname = "0.0.0.0";

const app = express();//app===express
const server = http.createServer(app);

app.get("/", (req, res) => {
    res.send("这是一个 后台express+node的接口api  index");
});
app.get("/ddemo", (req, res) => {
    res.json({
      code: 200,
      msg: '我是app.js的接口,不受token限制'
    })
});

server.listen(port, hostname, () => {
    console.log(`My express api server start successful at http://${hostname}:${port}`);
})
/************* 起服务结束 不用写在最后面  express在www里面 **************/

// 解决跨域
app.use(cors());//裸奔,任何人都可以访问

// session中间件: 是有跨域的,前端放在nginx是需要配置代理解决,不能用基路径(虽然后台是允许跨域的)
app.use(session({
  name:"my-server",
  saveUninitialized:true,
  secret:"mima",
  cookie:{maxAge:1000*60*60},  // session 保存时长  1hour 
  resave:false
}))


/************* 其他中间件 **************/
// .ejs(html预编译)
app.set('view engine', 'ejs');//设置模板引擎
app.use(logger('dev'));//使用(没有就设置)日志中间件
//设置中间件:将views "拆分" 到根目录(__dirname) -- 访问时跳过views
// views中的.ejs 是 利用.ejs实现js解析的html内容
app.set('views', path.join(__dirname, 'views'));
// 前面也可以加一个参数'/static',表示访问的是静态目录 -- 前缀地址(但没必要)
// 如果要使用多个静态资源目录，请多次调用 express.static 中间件函数
// 对外开放访问(不需要像views写路由才能访问)且"拆分" public(static静态目录) -- 不用写路由/ssr,"直接访问静态文件" -- 目的
// public  static   --  当做 服务器端的静态文件(js,img,css等等)
// 访问静态资源文件时，express.static 中间件函数会根据目录的添加顺序查找所需的文件。
app.use(express.static(path.join(__dirname, 'public')));
// app.use(express.static('public'));//简写
// // 使用req.body可以获取post请求的内容
// // 若没有这两句话: 则不能使用req.body获取
// // post 浏览器不能解析,打开会跳转404; 一般用测试工具postman
app.use(express.json());//获取 POST 请求的ForData数据 => 相当于$.post
app.use(express.urlencoded({ extended: false }));//表单Form action+name+value
// cookie
app.use(cookieParser());

// 检验token  (用了token,判断token匹配后才能进入/vue)-所以放在session后面,/vue的前面
// const { checkToken } = require("./utils/index");
// app.use(checkToken);

/**** 路由中间件 必须写在别的中间件后面,顺序执行的 ****/
app.use('/uni', vueRouter);


// catch 404 and forward to error handler
// app.use(function(req, res, next) {
//   next(createError(404));
// });

// // error handler
// app.use(function(err, req, res, next) {
//   // set locals, only providing error in development
//   res.locals.message = err.message;
//   res.locals.error = req.app.get('env') === 'development' ? err : {};

//   // render the error page
//   res.status(err.status || 500);
//   res.render('error');
// });
/******************** error **********************/
// 需配置path拆分error.ejs的views目录;安装ejs解析error.ejs
// 原始错误:Cannot GET /vue/moviea;写了这个监听错误后更详细
// catch 404 and forward to error handler
// app.use(function (req, res, next) {
//     // next 进入执行下一个中间件;必须写(不然没执行下一个,没写的省略了)
//     next(createError(404));
// });

// error handler  //参数err接上一个中间件的next中的404
// app.use(function (err, req, res, next) {
//     // set locals, only providing error in development
//     res.locals.message = err.message;
//     res.locals.error = req.app.get('env') === 'development' ? err : {};
//     // render the error page
//     // 状态码 500  服务器端报错
//     res.status(err.status || 500);
//     // render 渲染(SSR 服务器端)
//     // 是views中的error.ejs(但是被拆分;不需要写views)
//     // ejs 本质是一个js文件
//     res.render('error');// error会将你的详细错误报出来
// });
// 一个文件导出一个接口: 这里不用导出到www

module.exports = app;
